package jmind.core.dubbo;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import jmind.core.spring.SpringBeanFactory;
import jmind.base.util.AppEnvironment;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.utils.ConfigUtils;
import com.alibaba.dubbo.container.Container;

public class DubboServer {
    public static final String CONTAINER_KEY = "dubbo.container";

    public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";
    private static final Logger logger = LoggerFactory.getLogger(DubboServer.class);
    private static volatile boolean running = true;

    private static final ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);

    private static SpringBeanFactory context;

    public static SpringBeanFactory getSpringBeanFactory() {
        return context;
    }

    /**
     * $@
     * s.sh rebirth-dubbo-user.xml rebirth-dubbo-service.xml
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        if (args != null && args.length > 0) {
            context = new SpringBeanFactory(args);
        } else {
            context = new SpringBeanFactory("dubbo-server.xml");
        }

        try {

            String[] configs = Constants.COMMA_SPLIT_PATTERN.split(ConfigUtils.getProperty(CONTAINER_KEY,
                    loader.getDefaultExtensionName()));
            final List<Container> containers = new ArrayList<Container>();
            for (int i = 0; i < configs.length; i++) {
                containers.add(loader.getExtension(configs[i]));
            }
            System.out.println("Use container type(" + Arrays.toString(configs) + ") to run dubbo serivce. APP_ENV="
                    + AppEnvironment.getEnvironment());

            if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
                Runtime.getRuntime().addShutdownHook(new Thread() {
                    public void run() {
                        for (Container container : containers) {
                            try {
                                container.stop();
                                logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");
                            } catch (Throwable t) {
                                logger.error(t.getMessage(), t);
                            }
                            synchronized (DubboServer.class) {
                                running = false;
                                DubboServer.class.notify();
                            }
                        }
                    }
                });
            }

            for (Container container : containers) {
                container.start();
                logger.info("Dubbo " + container.getClass().getSimpleName() + " started!");
            }
            System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date())
                    + " Dubbo service server started!");

            //            System.out.println("dubbo rpc remote=" + RpcContext.getContext().getRemoteAddress() + ",local="
            //                    + RpcContext.getContext().getLocalHost());
        } catch (RuntimeException e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            System.exit(1);
        }
        synchronized (DubboServer.class) {
            while (running) {
                try {
                    DubboServer.class.wait();
                } catch (Throwable e) {
                }
            }
        }
    }

}
